package com.zed.games.repository;

import com.zed.api.games.Action;
import com.zed.api.games.GameAlreadyExistException;
import com.zed.api.games.GameBuilder;
import com.zed.api.games.GameBuilderRepository;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 缺省的游戏构建仓储
 *
 * @author Zed
 */
@Service
public class DefaultGameBuilderRepository extends GameBuilderLoaderWithSpi implements GameBuilderRepository {

    private Map<String, GameBuilder<?, ? extends Action>> builderMap;

    public DefaultGameBuilderRepository() {
        this.builderMap = new ConcurrentHashMap<>();
    }

    @Override
    public GameBuilder<?, ? extends Action> findById(String id) {
        return this.builderMap.get(id);
    }

    @Override
    public List<GameBuilder<?, ? extends Action>> getByIds(Collection<String> ids) {
        if (ids == null || ids.isEmpty()) return Collections.emptyList();
        return ids.stream()
                .map(el -> this.builderMap.get(el))
                .collect(Collectors.toList());
    }

    @Override
    public void registerGameBuilder(GameBuilder<?, ? extends Action> builder) throws GameAlreadyExistException {
        String id = builder.getId();
        if (this.builderMap.containsKey(id)) {
            throw new GameAlreadyExistException(id);
        }
        this.builderMap.put(builder.getId(), builder);
    }

    @SuppressWarnings("all")
    @Override
    public <G extends GameBuilder<?, ? extends Action>> G findById(String builderId, Class<G> clazz) {
        GameBuilder<?, ? extends Action> result = this.findById(builderId);
        if (clazz != null && result != null) {
            return clazz.cast(result);
        }
        return (G) result;
    }


    @Override
    protected void addGameBuilder(GameBuilder<?, ? extends Action> builder) throws GameAlreadyExistException {
        this.registerGameBuilder(builder);
    }
}
